 /*
The MIT License

Copyright (c) 2009 P.J. Onori (pj@somerandomdude.com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

package com.somerandomdude.colortoolkit
{
	import com.somerandomdude.colortoolkit.schemes.Analogous;
	import com.somerandomdude.colortoolkit.schemes.ColorList;
	import com.somerandomdude.colortoolkit.schemes.Complementary;
	import com.somerandomdude.colortoolkit.schemes.Compound;
	import com.somerandomdude.colortoolkit.schemes.FlippedCompound;
	import com.somerandomdude.colortoolkit.schemes.Monochrome;
	import com.somerandomdude.colortoolkit.schemes.SplitComplementary;
	import com.somerandomdude.colortoolkit.schemes.Tetrad;
	import com.somerandomdude.colortoolkit.schemes.Triad;
	import com.somerandomdude.colortoolkit.spaces.CMYK;
	import com.somerandomdude.colortoolkit.spaces.Gray;
	import com.somerandomdude.colortoolkit.spaces.HSB;
	import com.somerandomdude.colortoolkit.spaces.Lab;
	import com.somerandomdude.colortoolkit.spaces.RGB;
	import com.somerandomdude.colortoolkit.spaces.XYZ;
	
	public class Color extends CoreColor
	{
		/* @private */
		private var _cmyk:CMYK;
		/* @private */
		private var _rgb:RGB;
		/* @private */
		private var _hsb:HSB;
		/* @private */
		private var _gray:Gray;
		/* @private */
		private var _lab:Lab;
		/* @private */
		private var _xyz:XYZ;
		
		/* @private */
		private var _analogous:Analogous;
		/* @private */
		private var _analogousAngle:Number=10;
		/* @private */
		private var _analogousContrast:Number=25;
		/* @private */
		private var _complementary:Complementary;
		/* @private */
		private var _splitComplementary:SplitComplementary;
		/* @private */
		private var _compound:Compound;
		/* @private */
		private var _flippedCompound:FlippedCompound;
		/* @private */
		private var _monochrome:Monochrome;
		/* @private */
		private var _tetrad:Tetrad;
		/* @private */
		private var _tetradAngle:Number=90;
		/* @private */
		private var _triad:Triad;
		/* @private */
		private var _triadAngle:Number=120;
		
		public function get analogousScheme():ColorList
		{
			if(!_analogous) _analogous = new Analogous(_color, _analogousAngle, _analogousContrast);
			else _analogous.primaryColor=_color;
			
			return _analogous.colors;
		}
		
		public function get analogousAngle():Number { return _tetradAngle; }
		public function set analogousAngle(value:Number):void 
		{
			_analogousAngle=value;
			if(_analogous) _analogous.angle=value;
		}
		
		public function get analogousContrast():Number { return _tetradAngle; }
		public function set analogousContrast(value:Number):void 
		{
			_analogousContrast=value;
			if(_analogous) _analogous.contrast=value;
		}
		
		public function get complemenartyScheme():ColorList
		{
			if(!_complementary) _complementary = new Complementary(_color);
			else _complementary.primaryColor=_color;
			
			return _complementary.colors;
		}
		
		public function get splitComplementaryScheme():ColorList
		{
			if(!_splitComplementary) _splitComplementary = new SplitComplementary(_color);
			else _splitComplementary.primaryColor=_color;
			
			return _splitComplementary.colors;
		}
		
		public function get compoundScheme():ColorList
		{
			if(!_compound) _compound = new Compound(_color);
			else _compound.primaryColor=_color;
			
			return _compound.colors;
		}
		
		public function get flippedCompoundScheme():ColorList
		{ 
			if(!_flippedCompound) _flippedCompound = new FlippedCompound(_color);
			else _flippedCompound.primaryColor=_color;
			
			return _flippedCompound.colors;
		}
		
		public function get monochromeScheme():ColorList
		{ 
			if(!_monochrome) _monochrome = new Monochrome(_color);
			else _monochrome.primaryColor=_color;
			
			return _monochrome.colors;
		}
		
		public function get tetradScheme():ColorList
		{ 
			if(!_tetrad) _tetrad = new Tetrad(_color, _tetradAngle);
			else _tetrad.primaryColor=_color;
			
			return _tetrad.colors;
		}
		
		public function get tetradScheme2():ColorList
		{ 
			
			var tetrad:Tetrad = new Tetrad(_color, _tetradAngle);
			tetrad.alt=true;
			tetrad.primaryColor=_color;
			
			return tetrad.colors;
		}
		
		public function get tetradAngle():Number { return _tetradAngle; }
		public function set tetradAngle(value:Number):void 
		{
			if(!_tetrad) _tetrad = new Tetrad(_color, _tetradAngle);
			else _tetrad.angle=value;
		}
		
		public function get triadScheme():ColorList
		{ 
			if(!_triad) _triad = new Triad(_color, _triadAngle);
			else _triad.primaryColor=_color;
			
			return _triad.colors;
		}
		
		public function get triadAngle():Number { return _triadAngle; }
		public function set triadAngle(value:Number):void 
		{
			if(!_triad) _triad = new Triad(_color, _triadAngle);
			else _triad.angle=value;
		}
		
		/**
		 * Red color channel
		 * @return Number (between 0 and 255)
		 * 
		 */	
		public function get red():Number { return this._rgb.red; }
		
		/**
		 * Red color channel
		 * @param value Number (between 0 and 255)
		 * 
		 */	
		public function set red(value:Number):void
		{
			this._rgb.red=value;
			this._color=this._rgb.color;
		}
		
		/**
		 * Green color channel
		 * @return Number (between 0 and 255)
		 * 
		 */	
		public function get green():Number { return this._rgb.green; }
		
		/**
		 * Green color channel
		 * @param value Number (between 0 and 255)
		 * 
		 */	
		public function set green(value:Number):void
		{
			this._rgb.green=value;
			this._color=this._rgb.color;
		}
		
		/**
		 * Blue color channel
		 * @return Number (between 0 and 255)
		 * 
		 */	
		public function get blue():Number { return this._rgb.blue; }
		
		/**
		 * Blue color channel
		 * @param value Number (between 0 and 255)
		 * 
		 */	
		public function set blue(value:Number):void
		{
			this._rgb.blue=value;
			this._color=this._rgb.color;
		}
		
		/**
		 * Cyan color channel
		 * @return Number (between 0 and 100)
		 * 
		 */		
		public function get cyan():Number { return this._cmyk.cyan; }
		
		/**
		 * Cyan color channel
		 * @param value Number (between 0 and 100)
		 * 
		 */		
		public function set cyan(value:Number):void
		{
			this._cmyk.cyan=value;
			this.color=this._cmyk.color;
		}
		
		/**
		 * Magenta color channel
		 * @return Number (between 0 and 100)
		 * 
		 */			
		public function get magenta():Number { return this._cmyk.magenta; }
		
		/**
		 * Magenta color channel
		 * @param value Number (between 0 and 100)
		 * 
		 */	
		public function set magenta(value:Number):void
		{
			this._cmyk.magenta=value;
			this.color=this._cmyk.color;
		}
		
		/**
		 * Yellow color channel
		 * @return Number (between 0 and 100)
		 * 
		 */			
		public function get yellow():Number { return this._cmyk.yellow; }
		
		/**
		 * Yellow color channel
		 * @param value Number (between 0 and 100)
		 * 
		 */	
		public function set yellow(value:Number):void
		{
			this._cmyk.yellow=value;
			this.color=this._cmyk.color;
		}
		
		/**
		 * Black color channel
		 * @return Number (between 0 and 100)
		 * 
		 */			
		public function get black():Number { return this._cmyk.black; }
		
		/**
		 * Black color channel
		 * @param value Number (between 0 and 100)
		 * 
		 */	
		public function set black(value:Number):void
		{
			this._cmyk.black=value;
			this.color=this._cmyk.color;
		}
		
		/**
		 * Hue color value
		 * @return Number (between 0 and 360)
		 * 
		 */	
		public function get hue():Number { return this._hsb.hue; }
		
		/**
		 * Hue color value
		 * @param value Number (between 0 and 360)
		 * 
		 */
		public function set hue(value:Number):void
		{
			this._hsb.hue=value;
			this.color=this._hsb.color;
		}
		
		/**
		 * Saturation color value
		 * @return Number (between 0 and 100)
		 * 
		 */	
		public function get saturation():Number { return this._hsb.saturation; }
		
		/**
		 * Saturation color value
		 * @param value Number (between 0 and 100)
		 * 
		 */
		public function set saturation(value:Number):void
		{
			this._hsb.saturation=value;
			this.color=this._hsb.color;
		}
		
		/**
		 * Black color value
		 * @return Number (between 0 and 100)
		 * 
		 */	
		public function get brightness():Number { return this._hsb.brightness; }
		
		/**
		 * Black color value
		 * @param value Number (between 0 and 100)
		 * 
		 */	
		public function set brightness(value:Number):void
		{
			this._hsb.brightness=value;
			this.color=this._hsb.color;
		}
		
		/**
		 * Single gray channel value (not the hexidecimal color)
		 * @return Number (between 0 and 255)
		 * 
		 */	
		public function get gray():Number { return this._gray.gray; }
		
		public function get lightness():Number { return this._lab.lightness; }
		
		public function set lightness(value:Number):void
		{
			this._lab.lightness=value;
			this.color = this._lab.color;
		}
		
		public function get a():Number { return this._lab.a; }
		
		public function set a(value:Number):void
		{
			this._lab.a=value;
			this.color = this._lab.color;
		}
		
		public function get b():Number { return this._lab.b; }
		
		public function set b(value:Number):void
		{
			this._lab.b=value;
			this.color = this._lab.color;
		}
		
		public function get x():Number { return this._xyz.x; }
		
		public function set x(value:Number):void
		{
			this._xyz.x=value;
			this.color = this._xyz.color;
		}
		
		public function get y():Number { return this._xyz.y; }
		
		public function set y(value:Number):void
		{
			this._xyz.y=value;
			this.color = this._xyz.color;
		}
		
		public function get z():Number { return this._xyz.z; }
		
		public function set z(value:Number):void
		{
			this._xyz.z=value;
			this.color = this._xyz.color;
		}

		
		/**
		 * Hexidecimal RGB translation of color
		 * @return Hexidecimal color value
		 * 
		 */		
		public function get color():int { return this._color; }
		
		/**
		 * Hexidecimal RGB translation of color
		 * @param value Hexidecimal color value
		 * 
		 */		
		public function set color(value:int):void
		{
			this._color=value;
			this._cmyk.color=value;
			this._hsb.color=value;
			this._rgb.color=value;
			this._lab.color=value;
			this._xyz.color=value;
			this._gray.convertHexToGrayscale(value);
		}
		
		/**
		 * 
		 * @param color Hexidecimal color value
		 * 
		 */		
		public function Color(color:int)
		{
			this._cmyk = new CMYK();
			this._rgb = new RGB();
			this._hsb = new HSB();
			this._gray = new Gray();
			this._lab = new Lab();
			this._xyz = new XYZ();
			
			this.color=color;
			
		}

	}
}